package org.sofun.subscription.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sofun.subscription.model.FundPeriod;
import org.sofun.subscription.model.SubscriptionRule;
import org.sofun.subscription.service.SubscriptionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 申购服务控制器
 */
@RestController
@RequestMapping("/api/subscription")
public class SubscriptionController {

    private static final Logger logger = LoggerFactory.getLogger(SubscriptionController.class);

    @Autowired
    private SubscriptionService subscriptionService;
    
    /**
     * 生成申购开放日列表
     */
    @PostMapping("/open-days")
    public ResponseEntity<Map<String, Object>> generateOpenDays(
            @RequestBody SubscriptionRule rule,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate,
            @RequestParam(required = false) Integer periodCount) {

        logger.info("接收到生成开放日请求 - 开始日期: {}, 结束日期: {}, 期数: {}", startDate, endDate, periodCount);

        try {
            List<LocalDate> openDays = subscriptionService.generateOpenDaysWithExceptionHandling(
                rule, startDate, endDate, periodCount);

            logger.info("成功生成 {} 个开放日", openDays.size());

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("data", openDays);
            response.put("count", openDays.size());

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("生成开放日失败: {}", e.getMessage(), e);

            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("error", e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }
    
    /**
     * 计算基金期间列表
     */
    @PostMapping("/fund-periods")
    public ResponseEntity<Map<String, Object>> calculateFundPeriods(
            @RequestBody Map<String, Object> request) {

        logger.info("接收到计算募集期间请求");

        try {
            SubscriptionRule rule = parseSubscriptionRule(request);
            List<LocalDate> openDays = parseOpenDays(request);

            logger.debug("解析到 {} 个开放日", openDays != null ? openDays.size() : 0);

            List<FundPeriod> fundPeriods = subscriptionService.calculateFundPeriodsWithExceptionHandling(
                openDays, rule);

            logger.info("成功计算 {} 个募集期间", fundPeriods.size());

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("data", fundPeriods);
            response.put("count", fundPeriods.size());

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("计算募集期间失败: {}", e.getMessage(), e);

            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("error", e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }
    
    /**
     * 一站式服务：生成开放日并计算募集期间
     */
    @PostMapping("/complete")
    public ResponseEntity<Map<String, Object>> generateCompleteSchedule(
            @RequestBody SubscriptionRule rule,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate,
            @RequestParam(required = false) Integer periodCount) {

        logger.info("接收到一站式服务请求 - 开始日期: {}, 结束日期: {}, 期数: {}", startDate, endDate, periodCount);

        try {
            // 1. 生成开放日
            logger.info("开始生成开放日");
            List<LocalDate> openDays = subscriptionService.generateOpenDaysWithExceptionHandling(
                rule, startDate, endDate, periodCount);
            logger.info("成功生成 {} 个开放日", openDays.size());

            // 2. 计算募集期间
            logger.info("开始计算募集期间");
            List<FundPeriod> fundPeriods = subscriptionService.calculateFundPeriodsWithExceptionHandling(
                openDays, rule);
            logger.info("成功计算 {} 个募集期间", fundPeriods.size());

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("openDays", openDays);
            response.put("fundPeriods", fundPeriods);
            response.put("openDaysCount", openDays.size());
            response.put("fundPeriodsCount", fundPeriods.size());

            logger.info("一站式服务完成");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("一站式服务失败: {}", e.getMessage(), e);

            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("error", e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }
    
    /**
     * 健康检查接口
     */
    @GetMapping("/health")
    public ResponseEntity<Map<String, Object>> health() {
        logger.debug("健康检查请求");

        Map<String, Object> response = new HashMap<>();
        response.put("status", "UP");
        response.put("service", "SubscriptionService");
        response.put("timestamp", System.currentTimeMillis());

        logger.debug("健康检查响应: {}", response);
        return ResponseEntity.ok(response);
    }
    
    /**
     * 解析申购规则参数
     */
    private SubscriptionRule parseSubscriptionRule(Map<String, Object> request) {
        // 这里应该实现从Map到SubscriptionRule的转换逻辑
        // 为简化示例，这里返回null，实际使用时需要完善
        return (SubscriptionRule) request.get("rule");
    }
    
    /**
     * 解析开放日列表
     */
    @SuppressWarnings("unchecked")
    private List<LocalDate> parseOpenDays(Map<String, Object> request) {
        // 这里应该实现从Map到List<LocalDate>的转换逻辑
        // 为简化示例，这里返回null，实际使用时需要完善
        return (List<LocalDate>) request.get("openDays");
    }

}
